TokensService   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Test Coverage

Coverage 96.15%

Importance

Changes 0
Metric Value
eloc 52
dl 0
loc 65
ccs 25
cts 26
cp 0.9615
rs 10
c 0
b 0
f 0
wmc 10

4 Functions

Rating   Name   Duplication   Size   Complexity  
A revokeAllForUser 0 3 1
A findOne 0 7 2
A consume 0 18 4
A create 0 27 3
1 11
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
2 11
import { InjectRepository } from '@nestjs/typeorm';
3 11
import { Repository } from 'typeorm';
4 11
import { Token } from './entities/token.entity/token.entity';
5
6 11
const DEFAULT_MAX_USES = 10;
7 11
const DEFAULT_EXPIRATION_HOURS = 24;
8
9
@Injectable()
10 11
export class TokensService {
11
  constructor(
12
    @InjectRepository(Token)
13 14
    private readonly tokenRepository: Repository<Token>,
14
  ) {}
15
16
  async create(userId: string): Promise<Token> {
17 2
    const existingTokens = await this.tokenRepository.find({
18
      where: { customerId: userId },
19
    });
20 5
    const existingTokensRemainingUses = existingTokens.filter((token) => token.remainingUses > 0);
21
22 3
    if (existingTokens.length >= 5 && existingTokensRemainingUses.length > 0) {
23 1
      throw new BadRequestException(
24
        'Maximum number of tokens reached. Please consume an existing token before creating a new one.',
25
      );
26
    }
27
28 1
    if (existingTokens.length >= 5) {
29
      throw new BadRequestException('Maximum number of tokens reached');
30
    }
31
32 1
    const expiresAt = new Date();
33 1
    expiresAt.setHours(expiresAt.getHours() + DEFAULT_EXPIRATION_HOURS);
34 1
    const token = this.tokenRepository.create({
35
      customerId: userId,
36
      remainingUses: DEFAULT_MAX_USES,
37
      maxUses: DEFAULT_MAX_USES,
38
      expiresAt: expiresAt,
39
    });
40
41 1
    return this.tokenRepository.save(token);
42
  }
43
44
  async consume(id: string): Promise<Token> {
45 4
    const token = await this.tokenRepository.findOne({ where: { id } });
46
47 4
    if (!token) {
48 1
      throw new NotFoundException('Token not found');
49
    }
50
51 3
    if (token.remainingUses <= 0) {
52 1
      throw new BadRequestException('Token has no remaining uses');
53
    }
54
55 3
    if (token.expiresAt && token.expiresAt < new Date()) {
56 1
      throw new BadRequestException('Token has expired');
57
    }
58
59 1
    token.remainingUses--;
60 1
    return this.tokenRepository.save(token);
61
  }
62
63
  async findOne(id: string): Promise<Token> {
64 2
    const token = await this.tokenRepository.findOne({ where: { id } });
65 2
    if (!token) {
66 1
      throw new NotFoundException('Token not found');
67
    }
68 1
    return token;
69
  }
70
71
  revokeAllForUser(githubId: any) {
72 1
    return this.tokenRepository.delete({ customerId: githubId });
73
  }
74
}
75